﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Babylon.Toolbox;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Silverlight;
using Color = Microsoft.Xna.Framework.Color;
using Matrix = Microsoft.Xna.Framework.Matrix;

namespace Babylon.Toolkit.SplattingSample
{
    public partial class MainPage
    {
        readonly VertexPositionNormalTexture[] _quadVertices = new[]
        {
            new VertexPositionNormalTexture{Position = new Vector3(-1,1,0.5f), Normal = Vector3.Backward, TextureCoordinates = new Vector2(0,0)},
            new VertexPositionNormalTexture{Position = new Vector3(1,1,0.5f), Normal = Vector3.Backward, TextureCoordinates = new Vector2(1,0)}, 
            new VertexPositionNormalTexture{Position = new Vector3(-1,-1,0.5f), Normal = Vector3.Backward, TextureCoordinates = new Vector2(0,1)},
            new VertexPositionNormalTexture{Position = new Vector3(1,-1,0.5f), Normal = Vector3.Backward, TextureCoordinates = new Vector2(1,1)},
        };

        readonly ushort[] _quadIndices = new ushort[]
        {
            0,1,2,2,1,3
        };
        
        public MainPage()
        {
            InitializeComponent();
        }

        private VertexBuffer _vb;
        private IndexBuffer _ib;
        private SplattingEffect _effect;

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var gd = GraphicsDeviceManager.Current.GraphicsDevice;
            _vb = new VertexBuffer(gd, _quadVertices[0].VertexDeclaration, 4, BufferUsage.None);
            _vb.SetData(0, _quadVertices, 0, 4, _quadVertices[0].VertexDeclaration.VertexStride);
            _ib = new IndexBuffer(gd, IndexElementSize.SixteenBits, 6, BufferUsage.None);
            _ib.SetData(0, _quadIndices, 0, 6);
            _effect = new SplattingEffect(gd)
                          {
                              World = Matrix.Identity,
                              View = Matrix.Identity,
                              Projection = Matrix.Identity,
                              DiffuseColor = new Color(0.0f, 0.0f, 0.0f, 1.0f),
                              AmbientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f),
                              SceneAmbientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f),
                              DiffuseTexture = LoadTexture("wall.jpg", gd),
                              AlphaChannelsTexture = LoadTexture("channels.jpg", gd),
                              RedChannelTexture = LoadTexture("rocks.jpg", gd),
                              GreenChannelTexture = LoadTexture("stones.jpg", gd),
                              BlueChannelTexture = LoadTexture("wood.jpg", gd),
                              UVFactor = new Vector2(10, 10)
                          };
        }

        static Texture2D LoadTexture(string resource, GraphicsDevice gd)
        {
            var stream = Application.GetResourceStream(new Uri(resource, UriKind.Relative)).Stream;
            var bmp = new BitmapImage();
            bmp.SetSource(stream);
            Texture2D res = new Texture2D(gd, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);
            bmp.CopyTo(res);
            return res;
        }

        private void OnDraw(object sender, DrawEventArgs e)
        {
            e.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(1.0f, 1.0f, 1.0f, 1.0f), 1, 0);
            _effect.Device = e.GraphicsDevice;
            _effect.Apply();
            e.GraphicsDevice.Indices = _ib;
            e.GraphicsDevice.SetVertexBuffer(_vb);
            e.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
            e.InvalidateSurface();
        }
    }
}
